
#include "utils.h"



template<typename T>
void ptr_data_init(T* p,int n){
    for(int i=0;i<n;++i){
        p[i] = static_cast<T>(i%255);   
    }
}

template<>
void ptr_data_init(half* p,int n){
    for(int i=0;i<n;++i){
        p[i] = __float2half(static_cast<float>(i%255));
    }
}



template<typename T >
bool check_cpu_cuda_cal_result(T* A,T* B,int m,int k){
    for(int i=0;i<m;++i){
        for(int j=0;j<k;++j){
            if(A[i*k+j]-B[i*k+j]<1e-5) continue;
            return false;
        }
    }
    return true;
}

template<>
bool check_cpu_cuda_cal_result(half* A,half* B,int m,int k){
    for(int i=0;i<m;++i){
        for(int j=0;j<k;++j){
            float res = __half2float(A[i*k+j])-__half2float(B[i*k+j]);
            if(res<1e-5) continue;
            return false;
        }
    }
    return true;
}


HostTimer::HostTimer()
{
    t1 = std::chrono::steady_clock::now();
}

float HostTimer::getUsedTime()
{
    t2 = std::chrono::steady_clock::now();
    std::chrono::duration<double> time_used = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
    return(1000 * time_used.count()); // ms
}

HostTimer::~HostTimer()
{
}

DeviceTimer::DeviceTimer()
{
	cudaEventCreate(&start);
	cudaEventCreate(&end);
	cudaEventRecord(start);
}

float DeviceTimer::getUsedTime()
{
	cudaEventRecord(end);
	cudaEventSynchronize(end);
	float total_time;
	cudaEventElapsedTime(&total_time, start, end);
	return total_time;
}

DeviceTimer::DeviceTimer(cudaStream_t stream)
{
	cudaEventCreate(&start);
	cudaEventCreate(&end);
	cudaEventRecord(start, stream);
}

float DeviceTimer::getUsedTime(cudaStream_t stream)
{
	cudaEventRecord(end, stream);
	cudaEventSynchronize(end);
	float total_time;
	cudaEventElapsedTime(&total_time, start, end);
	return total_time;
}

DeviceTimer::~DeviceTimer()
{
	cudaEventDestroy(start);
	cudaEventDestroy(end);
}





template void ptr_data_init<float>(float*, int);
template void ptr_data_init<half>(half*, int);
template void ptr_data_init<uint8_t>(uint8_t*, int);


template bool check_cpu_cuda_cal_result<float>(float*, float*, int, int );
template bool check_cpu_cuda_cal_result<half>(half*, half*, int, int);
template bool check_cpu_cuda_cal_result<uint8_t>(uint8_t*, uint8_t* ,int ,int );